﻿using LNet;
using OestsCommon.Model;
using OestsDataBase;
using System;
using System.Net.Sockets;
using System.Threading;
using Utils;

/// <summary>
/// 用来跟客户端做通信 
/// </summary>
namespace OestsServer.Net
{
    public abstract class ClientChannel : TcpServer
    {
        /// <summary>
        /// 管理类
        /// </summary>
        /// 
        private ClientManager _manager;
        public ClientManager Manager
        {
            get { return _manager; }
            private set
            {
                _manager = value;
            }
        }
        public string listenerName;

        public static bool IsPrint = false;
        public string UserDes
        {
            get
            {
                if (User != null)
                {
                    return User.Number;
                }
                else
                {
                    return "无用户";
                }
            }
        }

        public string IPDes
        {
            get
            {
                if (IPPORT != null)
                    return IPPORT.ToString();
                else
                    return "";
            }
        }

        private string TimeDes
        {
            get
            {
                return DateTime.Now.ToLongTimeString();
            }
        }

        public User User { get; private set; }


        public Student Student
        {
            get
            {
                if (User == null) return null;
                return User as Student;
            }
        }

        public long lastPing = DateTime.Now.Ticks;
        public ClientChannel()
        {
        }

        public ClientChannel(string listenerName, Socket socket, ClientManager mng) 
        {
            this.listenerName = listenerName;
            this._worksocket = socket;
            Manager = mng;
            SignalAddListener();
            AsynRecive();//这里必须在最后调用
        }

        #region 通信

        public void Send(Response packet)
        {
            if (AsynSend(packet))
            {
                if (packet.ResponseCode == PacketKey.HeartBeat)
                    return;
                string sendInfo = packet.ResponseCode.ToString() + packet.ResponseSubCode + packet.ReturnCode + packet.DataStr;
                if (IsPrint)
                {
                    string info = string.Format("{0}[{1}][{2}][发送][{3}]", listenerName, IPDes, UserDes, sendInfo);
                    LogNetDebug.Log(info);
                }

            }
        }

        protected override void ReceiveHandler(Request request)
        {
            Recevie(request);

            string receInfo = request.RequestCode.ToString() + request.RequestSubCode + request.DataStr;
            if (IsPrint && request.RequestCode != PacketKey.HeartBeat)
            {
                string info = string.Format("{0}[{1}][{2}][收到][{3}]", listenerName, IPDes, UserDes, receInfo);
                LogNetDebug.Log(info);
            }
        }

        protected abstract void Recevie(Request request);

        //public override void TemporalDisConnectedHandler()
        //{
        //    if (IsConnected)
        //    {
        //        //timer.Stop();
        //        string info = string.Format("{0}[{1}][{2}]is disconnected,please waiting for reconnect", listenerName, IPDes, UserDes);
        //        LogNetDebug.Log(info);
        //        //manager.DisConnectedHandler(this);
        //    }
        //}


        public override void DisConnectedHandler()
        {
            string info = string.Format("{0}[{1}][{2}]is disconnected !", listenerName, IPDes, UserDes);
            LogNetDebug.Log(info);
            UpdateLogoutTime();
            Close();
            Manager.DeleteClient(this);

        }


        ~ClientChannel()
        {
            SignalRemoveListener();
        }

        #endregion

        #region 定义信号 发送消息 处理函数



        /// <summary>
        /// 添加信号事件
        /// </summary>
        public virtual void SignalAddListener() { }
        /// <summary>
        /// 移除信号事件
        /// </summary>
        public virtual void SignalRemoveListener() { }

        private void SendToID(int userId, Response packet)
        {
            if (User != null && User.DBid == userId)
            {
                Send(packet);
            }
        }

        #endregion

        private void Update()
        {
            while (true)
            {
                Thread.Sleep(5000);//刷新频率 5s
                #region 记录当前时间到数据库

                //UpdateLogoutTime();

                #endregion
            }

        }

        public void UpdateLoginTime()
        {
            User.LoginTime = DateTime.Now;
            //switch (User.Type)
            //{
            //    case UserType.Admin:
            //        AdminDAL.SaveLoginTime(User.DBid);
            //        break;
            //    case UserType.Teacher:
            //        TeacherDAL.SaveLoginTime(User.DBid);
            //        break;
            //    case UserType.Student:
            //        StudentDAL.SaveLoginTime(User.DBid);
            //        break;
            //}

            UserDAL.SaveLoginTime(User.DBid);

        }

        public void UpdateLogoutTime()
        {
            //  User.LogoutTime = DateTime.Now;
            //  UserDAL.SaveLogoutTime(User.DBid);

            //switch (User.Type)
            //{
            //    case UserType.Admin:
            //        AdminDAL.SaveLogoutTime(User.DBid);
            //        break;
            //    case UserType.Teacher:
            //    case UserType.Student:
            //        UserDAL.SaveLogoutTime(User.DBid);
            //        break;
            //}
        }

        public void SetUserData(User user)
        {
            if (user.Type == UserType.Student)
                User = new Student(user);
            else User = user;
        }

        public abstract bool CheckUserIsExist(/*UserType uType,*/ int userDbId);

        /// <summary>
        /// 返回教师id
        /// </summary>
        /// <returns></returns>
        public int GetTeacherId()
        {
            if (User.Type == UserType.Teacher)
            {
                return (User as Teacher).DBid;
            }
            return -1;
        }

        public int GetStudentId()
        {
            if (User is Student)
            {
                return (User as Student).DBid;
            }
            return -1;
        }
    }

}
